package com.zhen.lucene.file.search.controller;

import com.zhen.lucene.file.search.model.FileModel;
import com.zhen.lucene.file.search.service.IKAnalyzer6x;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;

/**
 * Created with IntelliJ IDEA.
 * User: zhen-desktop
 * Date: 2019/1/9
 * Time: 22:20
 */
public class SearchFileServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String indexpathStr = req.getServletContext().getRealPath("/indexdir");
        String query = req.getParameter("query");
        query = new String(query.getBytes("UTF-8"),"UTF-8");
        if(query == null || "".equals(query)){
            System.out.println("参数错误！");
            req.getRequestDispatcher("error.jsp").forward(req,resp);
        }else{
            ArrayList<FileModel> hitsList = getTopDoc(query,indexpathStr,100);
            System.out.println("共搜索到：" + hitsList.size() + "条数据!");
            req.setAttribute("hitsList",hitsList);
            req.setAttribute("queryback",query);
            req.getRequestDispatcher("result.jsp").forward(req,resp);
        }
        System.out.println("SearchFileServlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    public static ArrayList<FileModel> getTopDoc(String key,String indexpathStr,int N){
        ArrayList<FileModel> hitsList = new ArrayList<>();
        String[] fields = {"title","content"};
        Path indexPath = Paths.get(indexpathStr);
        Directory directory = null;
        try {
            directory = FSDirectory.open(indexPath);
            IndexReader reader = DirectoryReader.open(directory);
            IndexSearcher searcher = new IndexSearcher(reader);
            Analyzer analyzer = new IKAnalyzer6x();
            MultiFieldQueryParser parser2 = new MultiFieldQueryParser(fields,analyzer);
            Query query = parser2.parse(key);
            TopDocs topDocs = searcher.search(query,N);
            SimpleHTMLFormatter fors = new SimpleHTMLFormatter("<span style=\"color:red;\">","</span>");
            QueryScorer scoreTitle = new QueryScorer(query,fields[0]);
            Highlighter hlqTitle = new Highlighter(fors,scoreTitle);
            QueryScorer scoreContent = new QueryScorer(query,fields[1]);
            Highlighter hlqContent = new Highlighter(fors,scoreContent);
            TopDocs hits = searcher.search(query,100);
            for(ScoreDoc sd : topDocs.scoreDocs){
                Document doc = searcher.doc(sd.doc);
                String title = doc.get("title");
                String content = doc.get("content");
                TokenStream tokenStream = TokenSources.getAnyTokenStream(searcher.getIndexReader(),sd.doc,fields[0],new IKAnalyzer6x());
                Fragmenter fragmenter = new SimpleSpanFragmenter(scoreTitle);
                hlqTitle.setTextFragmenter(fragmenter);
                String h1_title = hlqTitle.getBestFragment(tokenStream,title);
                tokenStream = TokenSources.getAnyTokenStream(searcher.getIndexReader(),sd.doc,fields[1],new IKAnalyzer6x());
                fragmenter = new SimpleSpanFragmenter(scoreContent);
                hlqContent.setTextFragmenter(fragmenter);
                String h1_content = hlqContent.getBestFragment(tokenStream,content);
                FileModel fm = new FileModel(h1_title != null ? h1_title : title,h1_content != null ? h1_content : content);
                hitsList.add(fm);
            }
            directory.close();
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (InvalidTokenOffsetsException e) {
            e.printStackTrace();
        }
        return hitsList;
    }
}
